package com.WuZiQi;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.*;
import java.util.List;

public class GamePanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener {
    //落子指示器
    Step stepPointer=new Step();

    /** 对战方式（0-人机对战，1-人人对战） */
    int fightType;

    /** 先手选择（0-玩家先手，1-电脑先手） */
    int playFirst;

    /** 黑白选择（0-玩家执黑，1-玩家执白） */
    int chessColor;

    /** 判断游戏是否结束（true-结束，false-未结束） */
    boolean isGameOver = true;

    int 电脑棋子颜色 ;
    //player_ChessColor
    int 玩家棋子颜色 ;

    List<Step> 全谱 =new ArrayList<>();
    List<Step> 白谱 =new ArrayList<>();
    List<Step> 黑谱 =new ArrayList<>();
    List<Step> 胜谱 =new ArrayList<>();

    //右边的三个下拉框
    private JComboBox<String> Select_FightType,select_playFirst,select_chessColor;

    //右边的三个个按钮
    private JButton btn_new, btn_undo,btn_surrender;

    //右边的四个内容会发生变化的文本标签
    private JLabel txt_blackUndo, txt_blackState, txt_whiteUndo, txt_whiteState;

    //白棋的悔棋次数
    int whiteUndoNum=3;

    //黑棋的悔棋次数
    int blackUndoNum=3;




    //构造方法
    GamePanel(){
        this.setSize(Const.window_width, Const.window_height);
        this.setBackground(new Color(209,146,17));
        this.option();
        this.initGame();
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }

    void option(){
        this.setLayout(null);

        Font font =new Font("微软雅黑", Font.BOLD, 12);

        //=================对战方式===================
        JLabel txt1 = new JLabel("对战方式：");
        txt1.setFont(font);
        txt1.setForeground(Color.WHITE);
        txt1.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y, 100, 24);
        this.add(txt1);

        this.Select_FightType = new JComboBox<String>(new String[] { "人机对战", "人人对战" });
        this.Select_FightType.setFont(font);
        this.Select_FightType.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 30, 100, 24);
        this.add(this.Select_FightType);
        //=========================================

        //谁先手===============================================
        JLabel txt2 = new JLabel("先手选择：");
        txt2.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 70, 100, 24);
        txt2.setFont(font);
        txt2.setForeground(Color.WHITE);
        this.add(txt2);

        this.select_playFirst = new JComboBox<String>(new String[] { "玩家先手", "电脑先手" });
        this.select_playFirst.setFont(font);
        this.select_playFirst.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 100, 100, 24);
        this.add(this.select_playFirst);
        //===================================================

        //谁执黑===============================================
        JLabel txt3 = new JLabel("黑白选择：");
        txt3.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 140, 100, 24);
        txt3.setFont(font);
        txt3.setForeground(Color.WHITE);
        this.add(txt3);

        this.select_chessColor = new JComboBox<String>(new String[] { "玩家执黑", "玩家执白" });
        this.select_chessColor.setFont(font);
        this.select_chessColor.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 170, 100, 24);
        this.add(this.select_chessColor);
        //===================================================

        //开始游戏按钮
        this.btn_new = new JButton("开始游戏");
        this.btn_new.setFont(font);
        this.btn_new.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 230, 100, 30);
        this.add(this.btn_new);

        //悔棋按钮
        this.btn_undo = new JButton("我要悔棋");
        this.btn_undo.setFont(font);
        this.btn_undo.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 280, 100, 30);
        this.btn_undo.setEnabled(false);
        this.add(this.btn_undo);

        //认输按钮
        this.btn_surrender = new JButton("我认输了");
        this.btn_surrender.setFont(font);
        this.btn_surrender.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 330, 100, 30);
        this.btn_surrender.setEnabled(false);
        this.add(this.btn_surrender);

        // 黑棋提示组框===========================================
        JPanel groupBoxBlack = new JPanel();
        groupBoxBlack.setLayout(null);
        groupBoxBlack.setBackground(this.getBackground());
        groupBoxBlack.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 380, 100, 80);
        groupBoxBlack.setBorder(BorderFactory.createTitledBorder("黑棋"));
        this.add(groupBoxBlack);

        JLabel txt4 = new JLabel("悔棋：");
        txt4.setFont(font);
        txt4.setForeground(Color.WHITE);
        txt4.setBounds(10, 16, 40, 30);
        groupBoxBlack.add(txt4);

        this.txt_blackUndo = new JLabel("剩 " + this.blackUndoNum+ " 次");
        this.txt_blackUndo.setFont(font);
        this.txt_blackUndo.setForeground(Color.darkGray);
        this.txt_blackUndo.setBounds(44, 16, 50, 30);
        groupBoxBlack.add(this.txt_blackUndo);

        JLabel txt5 = new JLabel("状态：");
        txt5.setFont(font);
        txt5.setForeground(Color.WHITE);
        txt5.setBounds(10, 44, 40, 30);
        groupBoxBlack.add(txt5);

        this.txt_blackState = new JLabel("未开始");
        this.txt_blackState.setFont(font);
        this.txt_blackState.setForeground(Color.darkGray);
        this.txt_blackState.setBounds(44, 44, 50, 30);
        groupBoxBlack.add(this.txt_blackState);
        //===============================================

        //白棋提示组框 ===========================================
        JPanel groupBoxWhite = new JPanel();
        groupBoxWhite.setLayout(null);
        groupBoxWhite.setBackground(this.getBackground());
        groupBoxWhite.setBounds(Const.Top_Left_X + Const.Chessboard_Width + 30, Const.Top_Left_Y + 480, 100, 80);
        groupBoxWhite.setBorder(BorderFactory.createTitledBorder("白棋"));
        this.add(groupBoxWhite);

        JLabel txt6 = new JLabel("悔棋：");
        txt6.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        txt6.setForeground(Color.WHITE);
        txt6.setBounds(10, 16, 40, 30);
        groupBoxWhite.add(txt6);

        this.txt_whiteUndo = new JLabel("剩 " + this.whiteUndoNum + " 次");
        this.txt_whiteUndo.setFont(font);
        this.txt_whiteUndo.setForeground(Color.darkGray);
        this.txt_whiteUndo.setBounds(44, 16, 50, 30);
        groupBoxWhite.add(this.txt_whiteUndo);

        JLabel txt7 = new JLabel("状态：");
        txt7.setFont(font);
        txt7.setForeground(Color.WHITE);
        txt7.setBounds(10, 44, 40, 30);
        groupBoxWhite.add(txt7);

        this.txt_whiteState = new JLabel("未开始");
        this.txt_whiteState.setFont(font);
        this.txt_whiteState.setForeground(Color.darkGray);
        this.txt_whiteState.setBounds(44, 44, 50, 30);
        groupBoxWhite.add(this.txt_whiteState);
        //===================================================

        btn_new.setActionCommand("new");
        btn_new.addActionListener(this);

        btn_undo.setActionCommand("undo");
        btn_undo.addActionListener(this);

        btn_surrender.setActionCommand("surrender");
        btn_surrender.addActionListener(this);
        //后面,要给这些按钮加点击事件 ...



    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if(command == "new") {
            JOptionPane.showMessageDialog(this, "开始游戏");
//           游戏开始方法
            this.newGame();
        }
        else if(command == "undo") {
            JOptionPane.showMessageDialog(this, "悔棋");
        }
        else if(command == "surrender") {
            int r =JOptionPane.showConfirmDialog(this, "确定要认输吗","提示",JOptionPane.OK_CANCEL_OPTION);
            System.out.println(r); //确定为0, 取消为 2
        }
    }

    public void newGame() {
        //初始化游戏
        this.initGame();
        //设置控制区状态
        setComponentState(true);
        //游戏状态更改
        this.isGameOver=false;
        //fightType==0表示人机对战 playFirst==Const.black_1表示电脑先手
        if (this.fightType==0 && this.playFirst==Const.black_1){

        }
    }

    public void setComponentState(boolean isBegin) {
        if (isBegin) // 新游戏已经开始了
        {
            this.Select_FightType.setEnabled(false);
            this.select_playFirst.setEnabled(false);
            this.select_chessColor.setEnabled(false);
            this.btn_new.setEnabled(false);
            this.btn_undo.setEnabled(true);
            this.btn_surrender.setEnabled(true);
        } else // 新游戏还未开始
        {
            this.Select_FightType.setEnabled(true);
            this.select_playFirst.setEnabled(true);
            this.select_chessColor.setEnabled(true);
            this.btn_new.setEnabled(true);
            this.btn_undo.setEnabled(false);
            this.btn_surrender.setEnabled(false);
        }
    }


    void initGame() {
        this.isGameOver = true;
        // 清空下棋列表
        this.全谱.clear();
        this.黑谱.clear();
        this.白谱.clear();
        this.胜谱.clear();

        // 落子指示器初始化
        this.stepPointer.x = -1;
        this.stepPointer.y = -1;
        this.stepPointer.show = 0; // 0-不显示，1-显示

        // 对战方式
        if ("人人对战".equals(this.Select_FightType.getSelectedItem().toString())) {
            this.fightType = 1;
        } else {
            this.fightType = 0;
        }
        // 先手选择
        if ("电脑先手".equals(this.select_playFirst.getSelectedItem().toString())) {
            this.playFirst = 1;
        } else {
            this.playFirst = 0;
        }
        // 黑白选择
        if ("玩家执白".equals(this.select_chessColor.getSelectedItem().toString())) {
            this.chessColor = 1;
        } else {
            this.chessColor = 0;
        }

        // 电脑与玩家棋子颜色
        if (this.fightType == 0) {
            if (this.chessColor == 1) {
                this.电脑棋子颜色 = Const.black_1;
                this.玩家棋子颜色 = Const.white_2;

            } else {
                this.玩家棋子颜色 = Const.black_1;
                this.电脑棋子颜色 = Const.white_2;
            }
        }

    }
    void printChess(Graphics g) {
        g.setColor(Color.BLACK);
        for (int i = 0; i < Const.X_Grid_Number; i++) {

        }

    }
    public void paint(Graphics g) {
        super.paint(g);
        画棋盘(g);


        //往棋谱中添加一些模拟数据
        this.全谱.add(new Step(3,3,Const.white_2));
        this.全谱.add(new Step(4,4,Const.white_2));
        this.全谱.add(new Step(5,5,Const.black_1));
        this.全谱.add(new Step(7,5,Const.black_1));
        this.全谱.add(new Step(6,6,Const.white_2));
        this.全谱.add(new Step(7,8,Const.black_1));

        this.全谱.add(new Step(8,7,Const.white_2));
        this.全谱.add(new Step(9,8,Const.white_2));
        this.全谱.add(new Step(10,9,Const.white_2));
        this.全谱.add(new Step(11,10,Const.white_2));
        this.全谱.add(new Step(12,11,Const.white_2));

        画棋盘(g);

        画棋子(g,1,1,1);

//        this.stepPointer.x=5;
//        this.stepPointer.y=5;
//        this.stepPointer.show=1;

        画落子指示器(g);
        画五子成线(g);



    }

    private void 画五子成线(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        if (this.胜谱.size() == 5) {
            g2D.setColor(Color.RED);
            g2D.setStroke(new BasicStroke(2.5f));

            int x1 = 胜谱.get(0).x;
            int y1 = 胜谱.get(0).y;

            g2D.drawLine(Const.Top_Left_X + x1 * Const.Grid_width, Const.Top_Left_Y + y1 * Const.Grid_width,
                    Const.Top_Left_X + 胜谱.get(4).x * Const.Grid_width, Const.Top_Left_Y + 胜谱.get(4).y * Const.Grid_width);

        }
    }

    void 画棋盘 (Graphics g) {
        g.setColor(Color.BLACK);

        for (int i = 0; i < Const.X_Grid_Number; i++) {
            g.drawLine(Const.Top_Left_X, Const.Top_Left_Y + i * Const.Grid_width, Const.Top_Left_X + Const.Chessboard_Width,
                    Const.Top_Left_Y + i * Const.Grid_width);

            g.drawLine(Const.Top_Left_X + i * Const.Grid_width, Const.Top_Left_Y, Const.Top_Left_X + i * Const.Grid_width,
                    Const.Top_Left_Y + Const.Chessboard_Height);
        }

        // 画5个定位点
        // g.fillArc(x,y, d, d,180,180)
        // x坐标 y坐标 长 宽 开始弧度 结束弧度
        g.fillArc(Const.Top_Left_X + 3 * Const.Grid_width - 4, Const.Top_Left_Y + 3 * Const.Grid_width - 4, 8, 8, 0, 360);
        g.fillArc(Const.Top_Left_X + 15 * Const.Grid_width - 4, Const.Top_Left_Y + 3 * Const.Grid_width - 4, 8, 8, 0, 360);
        g.fillArc(Const.Top_Left_X + 9 * Const.Grid_width - 4, Const.Top_Left_Y + 9 * Const.Grid_width - 4, 8, 8, 0, 360);
        g.fillArc(Const.Top_Left_X + 3 * Const.Grid_width - 4, Const.Top_Left_Y + 15 * Const.Grid_width - 4, 8, 8, 0, 360);
        g.fillArc(Const.Top_Left_X + 15 * Const.Grid_width - 4, Const.Top_Left_Y + 15 * Const.Grid_width - 4, 8, 8, 0, 360);
    }
    void 画棋子(Graphics g,int x,int y, int flag) {
        for(Step step: 全谱) {
            // 将垂直与水平线的数目转化为像素
            int pX = Const.Top_Left_X + step.x * Const.Grid_width;
            int pY = Const.Top_Left_Y + step.y * Const.Grid_width;

            Graphics2D g2D = (Graphics2D) g;

            int color = step.single == Const.white_2 ? 90 : 10;

            RadialGradientPaint paint
                    = new RadialGradientPaint(pX, pY, color, new float[]{0f, 1f}, new Color[]{Color.WHITE, Color.BLACK});
            g2D.setPaint(paint);

            // 着色微调
            g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 消除画图锯齿

            Ellipse2D e = new Ellipse2D.Float(pX - Const.棋子直径 / 2, pY - Const.棋子直径 / 2, Const.棋子直径, Const.棋子直径);
            g2D.fill(e);
        }
    }
    void 画落子指示器(Graphics g) {
        if(this.stepPointer.show==1) {
            Graphics2D g2D = (Graphics2D) g;
            g2D.setColor(Color.RED);
            g2D.setStroke(new BasicStroke(2.5f));

            // 先以交叉点为中心取到指示器周围的4个角坐标
            // 中心点坐标
            int x = Const.Top_Left_X + stepPointer.x * Const.Grid_width;
            int y = Const.Top_Left_Y + stepPointer.y * Const.Grid_width;

            // 左上角坐标，并向下向右画线
            int x1 = x - Const.棋子直径 / 2;
            int y1 = y - Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 + Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 + Const.棋子直径 / 4, y1);

            // 右上角坐标，并向下向左画线
            x1 = x + Const.棋子直径 / 2;
            y1 = y - Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 + Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 - Const.棋子直径 / 4, y1);

            // 左下角坐标，并向上向右画线
            x1 = x - Const.棋子直径 / 2;
            y1 = y + Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 - Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 + Const.棋子直径 / 4, y1);

            // 右下角坐标，并向上向左画线
            x1 = x + Const.棋子直径 / 2;
            y1 = y + Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 - Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 - Const.棋子直径 / 4, y1);
        }
    }

    public void mouseClicked(MouseEvent e) {
        System.out.println("鼠标点击  mouseClicked");
    }

    public void mousePressed(MouseEvent e) {

    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {


    }

    public void mouseDragged(MouseEvent e) {

    }

    public void mouseMoved(MouseEvent e) {
        //为了暂时能看到落子指示器,先把它写成false,等正式运行的时候再改
        if(this.isGameOver==true) {
            return ;
        }

        //先让落子指示器不显示
        this.stepPointer.show=0;

        int x=e.getX();
        int y=e.getY();

        //判断鼠标是不是在棋盘范围之内
        if (x > (Const.Top_Left_X - Const.Grid_width / 2) && x < (Const.Top_Left_X + Const.Chessboard_Width + Const.Grid_width / 2)
                && y > (Const.Top_Left_Y - Const.Grid_width / 2) && y < (Const.Top_Left_Y + Const.Chessboard_Height + Const.Grid_width / 2)) {

            // 将x,y由像素改为相应的水平与垂直线的数目（0~19）
            int lineX = (x - Const.Top_Left_X + Const.Grid_width / 2) / Const.Grid_width;
            int lineY = (y - Const.Top_Left_Y + Const.Grid_width / 2) / Const.Grid_width;

            //判断该位置上是不是有棋子
            boolean hasChess = false;
            for (int i = 0; i < this.全谱.size(); i++) {
                Step step = this.全谱.get(i);
                if(step.x==lineX && step.y==lineY) {
                    hasChess=true;
                    break;
                }
            }

            if(hasChess==false) {
                this.stepPointer.x= lineX;
                this.stepPointer.y= lineY;
                this.stepPointer.show=1;
            }
        }
        else {//鼠标不在棋盘内,清除落子指示器
            this.stepPointer.show=0;
        }
        this.repaint();
    }

    public int getNextStepColor() {
        int color = -1;

        return color;
    }
}


